﻿using QDasConverter.Utils;
using QDasConverter.Forms;
using QDasConverter.Core;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Windows.Forms;
using WindGoes6.Database;
using WindGoes6.Forms;

namespace QDasConverter
{
    public partial class MainForm : Form
    {
        /// <summary>
        /// 用于定位上次在文件夹选择容体中的打开的文件夹。
        /// </summary>
        // ConfigurationData pd;

        /// <summary>
        /// 转换器模块，与具体业务关联。
        /// </summary>
        ConvertBase converter;

        /// <summary>
        /// SQL转换处理程序，负责多线程业务。
        /// </summary>
        SqlConvertProcessor scp;

        /// <summary>
        /// 运行日志。
        /// </summary>
        List<TransLog> currentLogs = new List<TransLog>();

        IniAccess ia = new IniAccess();

        SocketHost host = new SocketHost(10080);

        public MainForm()
        {
            InitializeComponent();
        }

        public void UpdateConverter()
        {
            // 从配置中初始化转换器模块。
            /**************************************
             * 转换器类型在这里确认
             * **************************************/
            var converterName = ia.ReadString(Config.Converter, "C2021T02_cvinet");

            // var converterName = ia.ReadString(Config.Converter, "C2021T04_DisenNVH");
            // converterName = "C2021T04_DisenNVH";
            Common.AddLog($"转换器 {converterName} 加载成功。", LogType.INFO);

            converter = Common.ConverterFactory(converterName);
            Common.AddLog($"初始化转换器 {converter?.DisplayName} 加载完成。", LogType.INFO);
            Text = " " + converter.DisplayName + " " + converter.Version.Split(',')[0];
        }

        private void NewMainForm_Load(object sender, EventArgs e)
        {
            UpdateConverter();

            dvCustomKField.EditMode = DataGridViewEditMode.EditOnEnter;
            dvCustomKField.Rows.Add("K2142", "单位", "测量值的单位", "mm");
            dvCustomKField.Rows[0].Cells[3].Value = ia.ReadString("K2142", "");
            DvCustomKField_Resize(null, null);
            tiLock.Visible = false;
            timer1.Start();
            tbMain.TabPages.RemoveAt(0);


            // 添加端口监听，默认端口为10080
            host = new SocketHost(ia.ReadInt("Port", 10080));
            host.Listen();
        }

        private void Scp_OneStepProcessCompleted(object sender, List<TransLog> logs)
        {
            lock (logs)
            {
                foreach (var e in logs)
                {
                    var item = e.ToStrings();
                    // Console.WriteLine("Items: " + string.Join(",", item));
                    ListViewItem lvi = new ListViewItem(item);
                    lvi.ImageIndex = e.LogType == LogType.INFO ? 0 : 3;
                    lvLogs.Items.Add(lvi);
                }
            }

            // 超过1000条则删除第0条。
            if (lvLogs.Items.Count > 1000)
                lvLogs.Items.RemoveAt(0);

            // 保持最新的日志可见。
            if (lvLogs.Items.Count > 0)
            {
                // lvLogs.Items[lvLogs.Items.Count - 1].Selected = true;
                try
                {
                    lvLogs.Items[lvLogs.Items.Count - 1].EnsureVisible();
                }
                catch { }
            }

            Application.DoEvents();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (currentLogs.Count == 0)
                return;

            lock (currentLogs)
            {
                int transed = 0;
                foreach (var log in currentLogs)
                {
                    //编号，0.时间，1.事件，2.原因，3.输出文件
                    lvLogs.Items.Insert(0, new ListViewItem(log.GetStrings()));
                    Common.AddLog(log?.ToFileString());
                    if (log.LogType == LogType.INFO)
                        transed++;

                    // 超过1000条则删除第0条。
                    if (lvLogs.Items.Count > 1000)
                        lvLogs.Items.RemoveAt(0);

                    // 保持最新的日志可见。
                    if (lvLogs.Items.Count > 0)
                        lvLogs.Items[lvLogs.Items.Count - 1].EnsureVisible();

                }
                currentLogs.Clear();
            }

            if (converter != null)
                tsLastResID.Text = "Last Converted Result ID: " + converter.LastResID.ToString();
        }

        private void tiStart_Click(object sender, EventArgs e)
        {
            StartConversion();
        }


        private void StartConversion()
        {
            // ConvertBase.DebugMode = ia.ReadString(Config.DebugMode, "0") == "1";

            // 检测输入文件夹是否存在
            converter.OutputDirectory = ia.ReadString(Config.OutputDirectory, Path.Combine(Application.StartupPath, "output"));
            Directory.CreateDirectory(converter.OutputDirectory);
            if (!Directory.Exists(converter.OutputDirectory))
            {
                Common.AddLog("输出文件夹不存在，必需配置输出文件夹位置，否则无法输出转换好的文件。 ", LogType.Error);
                return;
            }
            Common.AddLog($"输出文件夹 {converter.OutputDirectory} 检测通过。", LogType.INFO);

            // 检测临时文件夹是否存在 
            converter.TempDirectory = ia.ReadString(Config.TempDirectory, Path.Combine(Application.StartupPath, "temp"));
            Directory.CreateDirectory(converter.TempDirectory);
            if (!Directory.Exists(converter.TempDirectory))
            {
                Common.AddLog("临时文件不存在失败. ", LogType.Error);
                return;
            }
            Common.AddLog($"临时文件夹 {converter.TempDirectory} 检测通过。", LogType.INFO);

            if (converter == null)
            {
                Common.AddLog("转换器模块为null，无法启动线程。", LogType.Error);
                MessageBox.Show("转换器模块为null，无法启动线程。", "启动失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            converter.SqlConnectionString = ia.ReadString(Config.ConnectionString, true);
            if (converter.NeedConnectionCheck && converter.SqlConnectionString == null)
            {
                // converter.SqlConnectionString = values.ConnectionString1;
                Common.AddLog("连接字符串为null，无法启动线程。", LogType.Error);
                MessageBox.Show("连接字符串为null，无法启动线程。", "启动失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            Common.AddLog($"连接字符串读取完成：'{converter.SqlConnectionString}' ", LogType.INFO);

            // 创建转换任务
            scp = new SqlConvertProcessor(converter);
            scp.OneStepProcessCompleted += Scp_OneStepProcessCompleted;
            scp.ProcessExited += (sender, e) =>
            {
                tiStart.Enabled = true;
                tiStop.Enabled = false;
                Common.AddLog("主线程中止", LogType.INFO);
            };
            scp.Start();

            // 界面调整
            tbMain.SelectedIndex = 0;
            tiStart.Enabled = false;
            tiStop.Enabled = true;
        }


        private void tiSystemConfig_Click(object sender, EventArgs e)
        {
            tiConfig.PerformClick();
        }

        private void NewMainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            //if (pd.UI_AskBeforeClosing)
            {
                var res = MessageBox.Show("请问是否要退出？", "退出确认", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                if (res != DialogResult.Yes)
                {
                    e.Cancel = true;
                    return;
                }
            }

            try
            {
                if (scp != null)
                    scp.Stop();
            }
            catch { }

            //pd.IO_InputPaths.Clear();
            //pd.UI_InputListViewWidth.Clear();
            //pd.UI_InputListViewWidth.Add(new ListViewData(lvLogs));
        }

        private void tiLock_Click(object sender, EventArgs e)
        {

        }

        private void tiStop_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("确定要停止吗？", "转换停止确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                try
                {
                    scp.Stop();
                }
                catch { }
                tiStart.Enabled = true;
                tiStop.Enabled = false;
            }
        }

        private void tiOpenOutputFolder_Click(object sender, EventArgs e)
        {
            var path = ia.ReadString(Config.OutputDirectory);
            Funs.OpenFolderInWindows(path);
        }

        private void tiTransduceSelected_Click(object sender, EventArgs e)
        {
            StartConversion();
        }

        private void tiConfig_Click(object sender, EventArgs e)
        {
            ConfigForm cf = new ConfigForm();
            //cf.pd = pd.Clone();
            //cf.pd = pd;
            cf.ShowDialog();
            //if (cf.needSave)
            //{
            //    pd = cf.pd;
            //    pd.Save();
            //}

            UpdateConverter();
        }

        private void mnDeleteItem_Click(object sender, EventArgs e)
        {

        }

        private void mnOpenInputFolder_Click(object sender, EventArgs e)
        {

        }

        private void mnOpenFile_Click(object sender, EventArgs e)
        {

        }

        private void mnTransduce_Click(object sender, EventArgs e)
        {

        }


        private void mnNewConfig_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("是否重置所有配置参数？", "参数重置确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                converter.Initialize();
                MessageBox.Show("配置参数已重置成功。", "重置成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

        }

        private void mnExportConfig_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "xml文档|*.xml";
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                // pd.Save(sfd.FileName);
            }
        }

        private void mnSaveConfig_Click(object sender, EventArgs e)
        {
            //pd.UI_InputListViewWidth.Clear();
            //pd.UI_InputListViewWidth.Add(new ListViewData(lvLogs));

            //pd.Save();
            //MessageBox.Show("配置文件已经保存。", "保存成功。", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }


        private void tiClearLogList_Click(object sender, EventArgs e)
        {
            lvLogs.Items.Clear();
        }

        private void tiClear_Click(object sender, EventArgs e)
        {
            lvResults.Items.Clear();
        }

        private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void tiOpenLogFile_Click(object sender, EventArgs e)
        {
            tiOpenLogFile.Enabled = false;
            Process.Start("notepad.exe", ".\\runtime.log");
            tiOpenLogFile.Enabled = true;
        }

        private void tiSaveResults_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "text文档|*.txt";
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < lvResults.Items.Count; i++)
                {
                    sb.Append(lvResults.Items[i].Text + "\t");
                    for (int j = 0; j < lvResults.Items[i].SubItems.Count; j++)
                    {
                        sb.Append(lvResults.Items[i].SubItems[j].Text + "\t");
                    }
                    sb.AppendLine();
                }

                File.WriteAllText(sfd.FileName, sb.ToString());
            }
        }

        private void tiOpenAppFolder_Click(object sender, EventArgs e)
        {
            Process.Start("explorer.exe", ".");
        }

        private void DvCustomKField_Resize(object sender, EventArgs e)
        {
            KDescription.Width = dvCustomKField.Width - KName.Width - KUsage.Width - KValue.Width - 45;
        }

        private void DvCustomKField_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            for (int i = 0; i < dvCustomKField.Rows.Count; i++)
            {
                ia.WriteValue(dvCustomKField.Rows[i].Cells[0].Value.ToString(), dvCustomKField.Rows[i].Cells[3].Value.ToString());
            }
        }

        private void dbConnection_Click(object sender, EventArgs e)
        {
            var constr = ia.ReadString(Config.ConnectionString, true);
            ConTestForm ctf = new ConTestForm();
            if (!string.IsNullOrEmpty(constr))
                ctf.AddConnectionString(constr);
            ctf.ShowDialog();
            if (ctf.Connected && ctf.Connection != null)
            {
                ia.WriteValue(Config.ConnectionString, ctf.Connection.ConnectionString, true);
            }
        }

        private void tiSetID_Click(object sender, EventArgs e)
        {
            // new RangeForm().ShowDialog();
            Console.WriteLine(new C2021T01_Atlas().GetConfigurefileName());
        }

        private void tsAbout_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Version：" + converter.Version.Replace(',', '\n'));
        }

        private void tsConvertConfig_Click(object sender, EventArgs e)
        {
            tiSetID.PerformClick();
        }

        private void tsDBConfig_Click(object sender, EventArgs e)
        {
            dbConnection.PerformClick();
        }

        private void MainForm_Deactivate(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Hide();
                this.ShowInTaskbar = false;
            }
        }

        private void mnShowWindow_Click(object sender, EventArgs e)
        {
            this.Show();
            this.WindowState = FormWindowState.Normal;
            this.ShowInTaskbar = true;
        }

        private void mnHideWindow_Click(object sender, EventArgs e)
        {
            this.Hide();
            this.ShowInTaskbar = false;
        }

        private void mnExitApplication_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.Show();
            this.WindowState = FormWindowState.Normal;
            this.ShowInTaskbar = true;
        }
    }
}
